package compiler;
import java.io.*;
import java.util.*;
import br.ufpe.abaco.ParserGen.*;
import br.ufpe.abaco.ParserGen.List;
import br.ufpe.abaco.ParserGen.parser.SemanticAction;

import java.lang.reflect.*;
public class CompilerGenerator {
	
	ParserGen parser;
	public CompilerGenerator() {
		parser = new ParserGen();
		parser.generateTree(true);
	}
	
	public void whitespace(String regExp) throws CompilerException {
		parser.comment(regExp);
	}

	public void scan(String pack) throws Exception {
		File d = new File("bin/"+pack);
		File files[] = d.listFiles();
		for (File f: files) {
			String fileName = f.getName();
			if (fileName.endsWith(".class")) {
				fileName = fileName.substring(0, fileName.length()-6);
				Class<?> cl = Class.forName(pack+"."+fileName);
				if (cl.getSuperclass()==Syntax.class) {
					parser.nonTerminal(fileName);
				} else if (cl.getSuperclass()==Token.class) {
					RegExp r = cl.getAnnotation(RegExp.class);
					parser.nonTerminal(fileName);
					parser.terminal(fileName+"'", r.value(),true);
					parser.addProduction(fileName, fileName+"'", new ExecuteConstructor(cl.getConstructors()[0]));
				} else if (cl.isAnnotationPresent(Rule.class)) {
				}
			}
		}
		for (File f: files) {
			String fileName = f.getName();
			if (fileName.endsWith(".class")) {
				fileName = fileName.substring(0, fileName.length()-6);
				Class<?> cl = Class.forName(pack+"."+fileName);
				if (cl.getSuperclass()==Syntax.class) {
				} else if (cl.getSuperclass()==Token.class) {
				} else if (cl.isAnnotationPresent(Rule.class)) {
					Rule r = cl.getAnnotation(Rule.class);
					Constructor<?> ct = cl.getConstructors()[0];
					parser.addProduction(cl.getSuperclass().getSimpleName(),
							r.value(),new ExecuteConstructor(ct));
				}
			}
		}
		for (File f: files) {
			String fileName = f.getName();
			if (fileName.endsWith(".class")) {
				fileName = fileName.substring(0, fileName.length()-6);
				Class<?> cl = Class.forName(pack+"."+fileName);
				if (cl.getSuperclass()==Syntax.class) {
					parser.setStartSymbol(fileName);
				} else if (cl.getSuperclass()==Token.class) {
				} else if (cl.isAnnotationPresent(Rule.class)) {
				}
			}
		}
		parser.processCompiler();
		
		
	}
	
	public void test(String nt,String str) throws Exception {
		Object l = parser.compile(str,nt);
		System.out.println("Resultado = " + l);
		
	}
	public Object compile(String nt,String str) throws Exception {
		return parser.compile(str,nt);
	}
	
}

	